package com.smart.community.feign.common;

import feign.FeignException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.openfeign.FallbackFactory;

import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.util.Arrays;

/**
 * 通用Feign降级处理基类
 * 
 * 提供统一的降级处理模板，标准化日志记录格式和错误处理策略
 * 所有Feign降级工厂都应该继承此类，确保一致的降级处理行为
 * 
 * @author Wu.Liang
 * @version 2.0.0
 * @since 2025-01-30
 * @updated 2025-08-28 - 添加isServiceUnavailable方法，完善异常类型检查
 */
@Slf4j
public abstract class BaseFeignFallbackFactory<T> implements FallbackFactory<T> {
    
    /**
     * 记录服务不可用的日志
     * 使用WARN级别，记录关键信息但不产生过多错误日志
     * 
     * @param serviceName 服务名称
     * @param cause 异常原因
     */
    protected void logServiceUnavailable(String serviceName, Throwable cause) {
        log.warn("{}服务不可用，执行降级处理: {}", serviceName, cause.getMessage());
    }
    
    /**
     * 记录方法降级的日志
     * 使用DEBUG级别，记录详细的降级信息
     * 
     * @param methodName 方法名称
     * @param params 方法参数
     */
    protected void logMethodFallback(String methodName, Object... params) {
        log.debug("服务降级：{}方法，参数: {}", methodName, Arrays.toString(params));
    }
    
    /**
     * 记录方法降级的日志（简化版）
     * 使用DEBUG级别，只记录方法名称
     * 
     * @param methodName 方法名称
     */
    protected void logMethodFallback(String methodName) {
        log.debug("服务降级：{}方法", methodName);
    }
    
    /**
     * 获取服务名称
     * 子类可以重写此方法，提供具体的服务名称
     * 
     * @return 服务名称
     */
    protected abstract String getServiceName();
    
    /**
     * 检查是否为服务不可用异常
     * 
     * @param cause 异常原因
     * @return 是否为服务不可用
     */
    protected boolean isServiceUnavailable(Throwable cause) {
        return cause instanceof FeignException.ServiceUnavailable ||
               cause instanceof FeignException.NotFound ||
               cause instanceof ConnectException ||
               cause instanceof SocketTimeoutException;
    }
}
